home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
wdj0897.zip
/
TOMLINSN.ZIP
/
WDJSRVC.C
< prev
Wrap
C/C++ Source or Header
|
1997-05-29
|
7KB
|
246 lines
/*
bcc32 -w -DSTRICT clnt.c
bcc32 -w -DSTRICT wdjsrvc.c
---OR---
cl /W3 /DSTRICT clnt.c user32.lib
cl /W3 /DSTRICT wdjsrvc.c advapi32.lib user32.lib
*/
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
BOOL NotifySCM(DWORD, DWORD, DWORD);
VOID WINAPI ServiceMain(DWORD, LPTSTR *);
VOID WINAPI ServiceHandler(DWORD);
DWORD WINAPI WorkerThread(LPVOID);
VOID ProcessData(LPVOID Buffer, ULONG Size);
BOOL IsThreadAdmin(void);
HANDLE hDoneEvent = NULL, hThread = NULL;
DWORD dwCurrentState;
SERVICE_STATUS_HANDLE hService;
//--------------------------------------------------------------------
void main(void)
{
SERVICE_TABLE_ENTRY ServiceTable[] =
{{TEXT("WDJSrvc"), ServiceMain}, {NULL, NULL}};
StartServiceCtrlDispatcher(ServiceTable);
} // main
//------------------------------------------------------------------
#ifdef __BORLANDC__
# pragma argsused
#endif
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
DWORD ThreadId;
hService = RegisterServiceCtrlHandler(TEXT("WDJSrvc"), ServiceHandler);
if (!hService) {
return;
}
NotifySCM(SERVICE_START_PENDING, 0, 1);
hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hDoneEvent) {
return;
}
hThread = CreateThread(0, 0, WorkerThread, 0, 0, &ThreadId);
if (!hThread) {
CloseHandle(hDoneEvent);
return;
}
NotifySCM(SERVICE_RUNNING, 0, 0);
WaitForSingleObject(hDoneEvent, INFINITE);
CloseHandle(hThread);
CloseHandle(hDoneEvent);
return;
} // ServiceMain
//------------------------------------------------------------------
#ifdef __BORLANDC__
# pragma argsused
#endif
DWORD WINAPI WorkerThread(LPVOID ThreadParam)
{
TCHAR Buffer[1024];
HANDLE hPipe;
ULONG Status, Size;
PSECURITY_DESCRIPTOR pSecDesc;
SECURITY_ATTRIBUTES SecAttr;
//
// Create a security descriptor that gives access to EVERYONE
//
pSecDesc = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(pSecDesc,
SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(pSecDesc, TRUE, (PACL)NULL, FALSE);
SecAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
SecAttr.lpSecurityDescriptor = pSecDesc;
SecAttr.bInheritHandle = FALSE;
//
// create an instance of the pipe that we reuse for each client
//
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\wdjpipe1"),
PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 1024, 1024, 20000, &SecAttr);
if (hPipe == INVALID_HANDLE_VALUE) {
return FALSE;
}
while(TRUE) {
//
// Wait for a client to connect to this instance of the pipe
//
if (ConnectNamedPipe(hPipe, NULL) ||
GetLastError() == ERROR_PIPE_CONNECTED) {
while (TRUE) {
//
// Read client requests from the pipe.
//
Status = ReadFile(hPipe, Buffer, 1024, &Size, NULL);
if (Status && (Size > 0)) {
ImpersonateNamedPipeClient(hPipe);
ProcessData(Buffer, Size);
WriteFile(hPipe, Buffer, Size, &Size, NULL);
} else {
break;
}
}
RevertToSelf();
// let client read before disconnect
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
}
}
} // WorkerThread
//------------------------------------------------------------------
VOID ProcessData(LPVOID Buffer, ULONG Size)
{
INT Result;
LPWSTR UniBuffer = malloc(Size * sizeof(WCHAR)); // worst case
BOOL bUnicode = IsTextUnicode(Buffer, Size, &Result);
if (IsThreadAdmin()) { // based on Q118626
//
// Access allowed so process data, converting to unicode if
// necessary.
//
if (bUnicode) {
lstrcpy(UniBuffer, (LPCTSTR)Buffer);
} else {
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Buffer,
Size, UniBuffer, Size);
}
CharUpper(UniBuffer); // this is our trivial processing!!
} else {
lstrcpy(UniBuffer, L"ACCESS DENIED");
}
if (bUnicode) {
lstrcpy(Buffer, UniBuffer);
} else {
WideCharToMultiByte(CP_ACP, 0, UniBuffer, Size, Buffer,
Size, NULL, NULL);
}
free(UniBuffer);
} // ProcessData
//------------------------------------------------------------------
BOOL IsThreadAdmin(void)
{
HANDLE Token;
UCHAR InfoBuffer[1024];
PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer;
DWORD dwInfoBufferSize;
PSID psidAdministrators;
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
UINT x;
BOOL bSuccess;
if(!OpenThreadToken(GetCurrentThread(),TOKEN_READ,FALSE,&Token))
return(FALSE);
bSuccess = GetTokenInformation(Token,TokenGroups,InfoBuffer,1024,
&dwInfoBufferSize);
CloseHandle(Token);
if(!bSuccess)
return FALSE;
if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &psidAdministrators))
return FALSE;
bSuccess = FALSE;
for(x=0;x<ptgGroups->GroupCount;x++) {
if( EqualSid(psidAdministrators,ptgGroups->Groups[x].Sid) ){
bSuccess = TRUE;
break;
}
}
FreeSid(psidAdministrators);
return bSuccess;
} // IsThreadAdmin
//-----------------------------------------------------------------
VOID WINAPI ServiceHandler(DWORD fdwControl)
{
// For simplicity and brevity, this service doesn't support
// pausing and continueing.
switch(fdwControl) {
case SERVICE_CONTROL_STOP:
NotifySCM(SERVICE_STOP_PENDING, 0, 1);
SetEvent(hDoneEvent);
NotifySCM(SERVICE_STOPPED, 0, 0);
break;
case SERVICE_CONTROL_INTERROGATE:
NotifySCM(dwCurrentState, 0, 0);
break;
default:
break;
}
} // ServiceHandler
//------------------------------------------------------------------
BOOL NotifySCM(DWORD dwState,DWORD dwWin32ExitCode,DWORD dwProgress)
{
SERVICE_STATUS ServiceStatus;
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = dwCurrentState = dwState;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = dwProgress;
ServiceStatus.dwWaitHint = 5000;
return SetServiceStatus(hService, &ServiceStatus);
} // NotifySCM